﻿namespace Digitalmes.Application.Mes;

/// <summary>
/// 生产序列服务接口
/// </summary>
[ApiExplorerSettings(GroupName = "mes")]
public sealed class ProdSequenceService : IDynamicWebApiService
{
    private readonly SugarRepository<ProdWo> _woRepo;

    public ProdSequenceService(SugarRepository<ProdWo> woRepo)
    {
        _woRepo = woRepo;
    }

    /// <summary>
    /// 查询所有——分页
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<ProdWoDto>> GetPagesAsync(PageParam param)
    {
        // 筛选"已排产"后的单据
        // 按生产状态排序
        var query = await _woRepo.AsQueryable()
            .Includes(s => s.Product)
            .WhereIF(!string.IsNullOrWhiteSpace(param.Key), s => s.Wo.Contains(param.Key))
            .Where(s => s.Status >= WoStatusEnum.Scheduled)
            .OrderBy(s => s.Status)
            .ToPageAsync(param.Page, param.Limit);
        return query.Adapt<PageResult<ProdWoDto>>();
    }

    /// <summary>
    /// 工单下发
    /// </summary>
    /// <param name="models"></param>
    /// <returns></returns>
    [HttpPut]
    public async Task<int> IssueAsync(List<ProdWoDto> models)
    {
        var ids = models.Select(s => s.Id).ToArray();
        // 工单 "已排产" 才能下发
        var items = await _woRepo.GetListAsync(s => ids.Contains(s.Id) && s.Status == WoStatusEnum.Scheduled);
        if (!items.Any())
        {
            return 0;
        }

        items.ForEach(s =>
        {
            s.SetStatus(WoStatusEnum.Issued);
        });

        return await _woRepo
            .AsUpdateable(items)
            .UpdateColumns(s => new { s.Status, s.LastStatus, s.UpdateTime, s.UpdateUser })
            .ExecuteCommandAsync();
    }

    /// <summary>
    /// 工单暂停
    /// </summary>
    /// <param name="models"></param>
    /// <returns></returns>
    [HttpPut]
    public async Task<int> PauseAsync(List<ProdWoDto> models)
    {
        var ids = models.Select(s => s.Id).ToArray();
        // 工单处于 ["已下发", "生产中"] 状态才能暂停
        WoStatusEnum[] statuses = { WoStatusEnum.Issued, WoStatusEnum.Executing };
        var items = await _woRepo.GetListAsync(s => ids.Contains(s.Id) && statuses.Contains(s.Status));
        if (!items.Any())
        {
            return 0;
        }

        items.ForEach(s =>
        {
            s.SetStatus(WoStatusEnum.Paused);
        });

        return await _woRepo
            .AsUpdateable(items)
            .UpdateColumns(s => new { s.Status, s.LastStatus, s.UpdateTime, s.UpdateUser })
            .ExecuteCommandAsync();
    }

    /// <summary>
    /// 工单暂停恢复
    /// </summary>
    /// <param name="models"></param>
    /// <returns></returns>
    [HttpPut]
    public async Task<int> UnPauseAsync(List<ProdWoDto> models)
    {
        var ids = models.Select(s => s.Id).ToArray();
        // 工单 "已暂停" 才能取消暂停
        var items = await _woRepo.GetListAsync(s => ids.Contains(s.Id) && s.Status == WoStatusEnum.Paused);
        if (!items.Any())
        {
            return 0;
        }

        items.ForEach(s =>
        {
            s.RecoverStatus();
        });

        return await _woRepo
            .AsUpdateable(items)
            .UpdateColumns(s => new { s.Status, s.LastStatus, s.UpdateTime, s.UpdateUser })
            .ExecuteCommandAsync();
    }

    /// <summary>
    /// 工单冻结
    /// </summary>
    /// <param name="models"></param>
    /// <returns></returns>
    [HttpPut]
    public async Task<int> FreezeAsync(List<ProdWoDto> models)
    {
        var ids = models.Select(s => s.Id).ToArray();
        // 工单 "已排产" 才能下发
        var items = await _woRepo.GetListAsync(s => ids.Contains(s.Id) && s.Status == WoStatusEnum.Scheduled);
        if (!items.Any())
        {
            return 0;
        }

        items.ForEach(s =>
        {
            s.SetStatus(WoStatusEnum.Freezed);
        });

        return await _woRepo
            .AsUpdateable(items)
            .UpdateColumns(s => new { s.Status, s.LastStatus, s.UpdateTime, s.UpdateUser })
            .ExecuteCommandAsync();
    }
}
